using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using MinoChat.Data.Entities;
using MinoChat.Data.Services.Interfaces;
using MinoChat.Messages;
using MinoChat.Services.Interfaces;
using MinoChat.Views.Pages;
using MinoChat.Enums;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Windows;
using Microsoft.Extensions.Logging;

namespace MinoChat.ViewModels;
/*
   MainViewModel → Send(SessionChangedMessage{sessionId}) → Messenger
   Messenger → Receive(SessionChangedMessage → ChatPageViewModel
   ChatPageViewModel → LoadSessionAsync(sessionId) → IChatDataService
   ChatPageViewModel → SaveMessageAsync() → IChatDataService
 */
public partial class MainViewModel : ObservableObject
{
    private readonly INavigationService _navigationService;
    private readonly IChatDataService _chatDataService;
    private readonly ILogger<MainViewModel> _logger;

    [ObservableProperty]
    private ObservableCollection<ChatSession> _chatSessions = new();

    // 属性改变时候会触发OnSelectedChatSessionChanged方法
    // 属性改变时ListView控件会自动在UI上找到对应的项ListViewItem，IsSelected属性设为true高亮显示，这种联动是双向的
    [ObservableProperty]
    private ChatSession? _selectedChatSession;

    [ObservableProperty]
    private string _inputMessage = string.Empty;

    [ObservableProperty]
    private bool _isInputEnabled = true;

    [ObservableProperty]
    private UserControl? _currentPage;

    public MainViewModel( INavigationService navigationService, IChatDataService chatDataService, ILogger<MainViewModel> logger)
    {
        _navigationService = navigationService;
        _chatDataService = chatDataService;
        _logger = logger;
        // 异步加载聊天会话数据
        _ = LoadChatSessionsAsync();
        // 订阅标题变更消息
        WeakReferenceMessenger.Default.Register<SessionTitleChangedMessage>(this, (r, m) =>
        {
            // 在UI线程上更新标题和模型
            Application.Current.Dispatcher.Invoke(() =>
            {
                var session = ChatSessions.FirstOrDefault(s => s.Id == m.Value.SessionId);
                if (session != null)
                {
                    var index = ChatSessions.IndexOf(session);
                    if (index >= 0)
                    {
                        // 更新标题和模型
                        session.Title = m.Value.Title;
                        session.Model = m.Value.Model;
                        // 通过移除再插入来触发集合变更通知，确保UI刷新
                        ChatSessions.RemoveAt(index);
                        ChatSessions.Insert(index, session);
                        // 只有不是当前选中的会话才重新设置选中状态
                        // 如果是当前选中的会话，不需要重新设置，避免触发不必要的重新加载
                        if (SelectedChatSession?.Id != session.Id)
                        {
                            SelectedChatSession = session;
                        }
                        _logger.LogInformation("UI已更新会话，标题: {Title}, 模型: {Model}", m.Value.Title, m.Value.Model);
                    }
                }
            });
        });
    }
    private async Task LoadChatSessionsAsync()
    {
        try
        {
            var sessions = await _chatDataService.LoadChatSessionsAsync();
            // 在UI线程上变更绑定集合，更新UI显示
            Application.Current.Dispatcher.Invoke(() =>
            {
                ChatSessions.Clear();
                foreach (var session in sessions.OrderByDescending(s => s.LastMessageTime))
                {
                    ChatSessions.Add(session);
                }
                SelectedChatSession = ChatSessions.FirstOrDefault();
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "加载聊天会话失败");
        }
    }

    // 当选中的会话改变时，发送消息通知ChatPageViewModel加载对应会话
    partial void OnSelectedChatSessionChanged(ChatSession? oldValue, ChatSession? newValue)
    {
        if (newValue != null)
        {
            // 只有在窗口已加载后才导航（避免初始化时ContentControl为空）
            if (Application.Current.MainWindow?.IsLoaded == true)
            {
                Navigate(PageType.Chat);
            }
            // 然后发送会话切换消息
            // Dispatcher.BeginInvoke确保导航完成页面加载，并且确认已经订阅消息后再发送消息
            Application.Current.Dispatcher.BeginInvoke(() =>
            {
                //ChatPageViewModel会接收到这个消息并根据SessionId加载对应ChatMessage
                WeakReferenceMessenger.Default.Send(new SessionChangedMessage(newValue.Id));
            });
        }
    }

    [RelayCommand]
    private async Task CreateNewChat()
    {
        var welcomeMessage = new ChatMessage
        {
            Content = "我有什么可以帮助你的呢？",
            IsUserMessage = false,
            Timestamp = DateTime.Now,
            SequenceNumber = 0
        };
        var newSession = new ChatSession
        {
            Title = "新的对话",
            Model = "Mino-Chat", // 默认显示，首次AI回复时会更新为实际使用的模型
            LastMessageTime = DateTime.Now,
            Messages = new List<ChatMessage> { welcomeMessage }
        };

        ChatSessions.Insert(0, newSession); // 插入到顶部
        // 虽然不是在前台UI选择，但同样会触发OnSelectedChatSessionChanged
        SelectedChatSession = newSession;
        // 将新建会话保存到数据库中
        await _chatDataService.SaveChatSessionAsync(newSession);
        // 确保在创建新会话后导航到聊天页面
        Navigate(PageType.Chat);
    }

    [RelayCommand]
    private void Navigate(PageType pageType)
    {
        switch (pageType)
        {
            case PageType.Chat:
                _navigationService.NavigateTo<ChatPage>();
                break;
            case PageType.Mask:
                _navigationService.NavigateTo<MaskPage>();
                break;
            case PageType.Settings:
                _navigationService.NavigateTo<SettingsPage>();
                break;
            case PageType.Search:
                _navigationService.NavigateTo<SearchPage>();
                break;
            default:
                throw new ArgumentOutOfRangeException(nameof(pageType), pageType, null);
        }
        CurrentPage = _navigationService.CurrentPage;
    }

    [RelayCommand]
    private void NavigateToChat()
    {
        Navigate(PageType.Chat);
    }

    [RelayCommand]
    private async Task DeleteChatSession(ChatSession session)
    {
        if (session == null) return;
        ChatSessions.Remove(session);
        // 从数据库中删除
        await _chatDataService.DeleteChatSessionAsync(session.Id);
        // 仅在没有会话时创建新会话
        if (ChatSessions.Count == 0)
        {
            await CreateNewChat();
        }
        else
        {
            // 选择下一个会话(优先选择第一个)
            SelectedChatSession = ChatSessions.FirstOrDefault();
        }
    }
}